/**
 * OSS is a Open Service Container which gives the leverage of building the Desktop and Web
 * Application. * Copyright (C) 2008-2009  Ponraj Sutanthiramani
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Or5e Open Source Community
 * 105, S.S Paradise Apartment, Munnireddy Layout, Horamavu, Banaswadi, Bangalore, India.
 */
package org.or5e.api.server;

import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.or5e.core.BaseObject;
import org.or5e.core.EventTypes.TCP_EVENT;

public class RequestProcessor extends BaseObject implements IoHandler {
	private Map<String, List<CmdListener>> cmdListener = null;
	private final String LNFD = "\r";
	private final String DELIMITER = "|";
	public static final String LOGINCMD="A001|LOGIN";
	public static final String LOGOUTCMD="A001|LOGOUT";
	
	public RequestProcessor(Map<String, List<CmdListener>> cmdListener) {
		this.cmdListener = cmdListener;
	}

	@Override
	public void exceptionCaught(IoSession arg0, Throwable exception) throws Exception {
		debug("Exception Raised:"+exception.getMessage());
	}

	@Override
	public void messageReceived(IoSession session, Object message) throws Exception {
		String messageReceived = (String) message;

		String[] tokens = parseTokens(messageReceived);

		callCommandListeners(TCP_EVENT.MESSAGE_RECEIVED, tokens, null);

		session.write("Command Recived."+LNFD);

		userSessionOperations(session, messageReceived, tokens);
	}

	private void userSessionOperations(IoSession session, String messageReceived, String[] tokens) {
		//CHECK FOR New Session Login ID.
		if(messageReceived.startsWith(LOGINCMD)) {
			session.setAttribute("USERNAME", tokens[2]);
		}
		//CHECK FOR CLOSING THE SESSION.
		if(messageReceived.startsWith(LOGOUTCMD)) session.close(Boolean.TRUE);
	}

	private String[] parseTokens(String messageReceived) {
		// Parse Tokens
		StringTokenizer messageTokens = new StringTokenizer(messageReceived, DELIMITER);
		String[] tokens = new String[messageTokens.countTokens()];
		int index = 0;
		while(messageTokens.hasMoreTokens()) {
			tokens[index++] = messageTokens.nextToken();
		}
		return tokens;
	}

	private void callCommandListeners(TCP_EVENT evtType, String[] message, IoSession session) {
		if(this.cmdListener == null) return;
		List<CmdListener> cmdListenerList = this.cmdListener.get(message[0]+DELIMITER+message[1]);
		if(cmdListenerList != null) {
			for (CmdListener cmdListener : cmdListenerList) {
				cmdListener.cmdReceived(new CommandEvent(evtType, message, session));
			}
		}
	}

	@Override
	public void messageSent(IoSession session, Object sendMessage) throws Exception {
//		callCommandListeners(CommandEvent.EVENT_TYPE.MESSAGE_SEND, null, null);
	}

	@Override
	public void sessionClosed(IoSession session) throws Exception {
		String[] tokens = parseTokens(LOGOUTCMD+session.getAttribute("USERNAME"));
		callCommandListeners(TCP_EVENT.SESSION_CLOSED, tokens, session);
	}

	@Override
	public void sessionCreated(IoSession session) throws Exception {
		String[] tokens = parseTokens(LOGINCMD);
		callCommandListeners(TCP_EVENT.SESSION_CREATED, tokens, session);
	}

	@Override
	public void sessionIdle(IoSession session, IdleStatus idleStatus) throws Exception {

	}

	@Override
	public void sessionOpened(IoSession session) throws Exception {

	}

	@Override
	public String getName() {
		return "RequestProcessor";
	}
}